package com.bjsxt.config.shiro;

import com.bjsxt.domain.User;
import com.bjsxt.service.UserService;
import com.bjsxt.vo.ActiveUser;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;

/**
 * @author:liao
 * @Description:TODO 该类重写的方法会
 *                  在controller中调用login方法时回调
 * @date:2020/11/19
 */
public class UserRealm extends AuthorizingRealm {

    @Autowired //bytyoe
    @Lazy//懒加载
    private UserService userService;

    //获取当前类名
    @Override
    public String getName() {
        return this.getClass().getSimpleName();
    }

    /**
     * 授权方法 登录成功后授予用户权限
     * @param principals
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        // 认证通过后 获取存入主体的用户信息进行授权
        ActiveUser activeUser = (ActiveUser) principals.getPrimaryPrincipal();
        // 此处暂时不用授权
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        return info;
    }

    /**
     * 认证方法---也就是登录
     * @param token
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        //获取登录时的电话号
        String phone = token.getPrincipal().toString();
        //根据电话号码查找用户是否存在
        User user = userService.queryUserByPhone(phone);
        //若用户存在 将用户信息交由shiro去进行判断密码
        if (user!=null){
            //组装activeUser
            ActiveUser activeUser = new ActiveUser();
            activeUser.setUser(user);
            /**
             * TODO
             *      第一个参数表示要保存在shiro中的用户信息
             *      第二个参数表示数据库中的密码
             *      第三个参数表示数据库密码中加的盐
             *      第四个参数表示当前类名
             */
            SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(
                    activeUser,
                    user.getPassword(),
                    ByteSource.Util.bytes(user.getSalt()),
                    this.getName()
            );
            // 将用户信息返回至主体
            return info;
        }
        // 返回null时表示用户不存在
        return null;
    }
}
